﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace SIMCObjetoNegocio
{
    public static class Extensiones
    {
        public static int Buscar(this List<FuncionConSeguridad> p_Lista, Func<FuncionConSeguridad, bool> p_Query)
        {
            return p_Lista.Where(p_Query).Count();
        }

        public static bool ExisteEvento(this List<FuncionConSeguridad> p_Lista, string p_Evento)
        {
            return p_Lista.Where(p => p.Evento == p_Evento).Count() > 0;
        }

        public static string Imprimir(this TipoPosicion p_Tipo)
        {
            switch (p_Tipo)
            {
                case TipoPosicion.AccionesComunes: return "Acciones Comunes";
                case TipoPosicion.AccionesPreferidas: return "Acciones Preferidas";
                case TipoPosicion.ADR_ADS: return "ADR_ADS";
                case TipoPosicion.EfectivoVista: return "Efectivo a la Vista";
                case TipoPosicion.FondosMutuales: return "Fondos Mutuales";
                case TipoPosicion.MutuosRentaFija: return "Mutuos Renta Fija";
                case TipoPosicion.MutuosRentaVariable: return "Mutuos Renta Variable";
                case TipoPosicion.OpcionCompra: return "Opcion Compra";
                case TipoPosicion.OpcionVenta: return "Opcion Venta";
                case TipoPosicion.OperacionesFinanciamientoPlazo: return "Operaciones Financiamiento Plazo";
                case TipoPosicion.OperacionesForward: return "Operaciones Forward";
                case TipoPosicion.OperacionesTransito: return "Operaciones en Transito";
                case TipoPosicion.TipoNoDisponible: return "Tipo No Disponible";
                case TipoPosicion.ValoresRentaFija: return "Valores Renta Fija";
                default: return string.Empty;
            }
        }

        public static IList<PortafolioBalancePosicion> FiltrarPorTipo(this IList<PortafolioBalancePosicion> p_Posiciones, TipoPosicion p_Tipo)
        {
            return p_Posiciones.Where(p => p.TipoGenericoEnum == p_Tipo).ToList();
        }

        public static IList<PortafolioBalancePosicion> FiltrarActivoPasivo(this IList<PortafolioBalancePosicion> p_Posiciones, ActivoPasivo p_AP)
        {
            return p_Posiciones.Where(p => p.APEnum == p_AP).ToList();
        }

        public static decimal? TotalValorPorTipo(this IList<PortafolioBalancePosicion> p_Posiciones, TipoPosicion p_Tipo, ActivoPasivo p_AP)
        {
            return p_Posiciones.Where(p => (p.TipoGenericoEnum == p_Tipo && p.APEnum == p_AP)).Select(p => p.ValorPosicionBase).Sum();
        }
        public static decimal? TotalValor(this IList<PortafolioBalancePosicion> p_Posiciones)
        {
            return p_Posiciones.Select(p => p.ValorPosicionBase).Sum();
        }

        public static decimal? TotalPorcentajeActivoPorTipo(this IList<PortafolioBalancePosicion> p_Posiciones, TipoPosicion p_Tipo, ActivoPasivo p_AP)
        {
            return p_Posiciones.Where(p => (p.TipoGenericoEnum == p_Tipo && p.APEnum == p_AP)).Select(p => p.PorcentajeDelActivo).Sum();
        }

        public static decimal? TotalPorcentaje(this IList<PortafolioBalancePosicion> p_Posiciones)
        {
            return p_Posiciones.Select(p => p.PorcentajeDelActivo).Sum();
        }

        public static List<TipoPosicion> BuscarTipoGenericosDisponibles(this IList<PortafolioBalancePosicion> p_Posiciones)
        {
            return p_Posiciones.Select(p => p.TipoGenericoEnum).Distinct().ToList();
        }

        public static DateTime BuscarFechaInicialDelAnno(this DateTime fecha)
        {
            return new DateTime(fecha.Year - 1, 12, 31);
        }
        public static DateTime BuscarFechaInicialDelTrimestre(this DateTime fecha)
        {
            int mes = fecha.Month;
            DateTime fechaRetorno = new DateTime();

            if ((mes == 1) || (mes == 4) || (mes == 7) || (mes == 10))
            {
                fechaRetorno = new DateTime(fecha.Year, fecha.Month, 1);
            }
            else
            {
                if ((mes > 1) && (mes <= 3))
                {
                    fechaRetorno = new DateTime(fecha.Year, 1, 1);
                }
                else
                    if ((mes > 3) && (mes <= 6))
                    {
                        fechaRetorno = new DateTime(fecha.Year, 4, 1);
                    }
                    else
                        if ((mes > 6) && (mes <= 9))
                        {
                            fechaRetorno = new DateTime(fecha.Year, 7, 1);
                        }
                        else
                            if (mes > 9)
                            {
                                fechaRetorno = new DateTime(fecha.Year, 10, 1);
                            }
                            else
                                fechaRetorno = fecha;
            }
            return fechaRetorno.AddDays(-1);
        }
        public static DateTime BuscarFechaInicialDelMes(this DateTime fecha)
        {
            return new DateTime(fecha.Year, fecha.Month, 1).AddDays(-1);
        }

        public static List<AporteORetiro> Aportes(this List<AporteORetiro> ar)
        {
            return ar.Where(p => p.IngresoEgreso == "I").ToList();
        }

        public static List<AporteORetiro> Retiros(this List<AporteORetiro> ar)
        {
            return ar.Where(p => p.IngresoEgreso == "E").ToList();
        }

        public static List<double> FlujoMensual(this List<AporteORetiro> ar, DateTime FechaInicial, DateTime FechaFinal, double NetoInicial, double NetoFinal)
        {
            Dictionary<DateTime, double> listTemp = new Dictionary<DateTime, double>();
            if (ar.Count > 0)
            {
                DateTime fechaTemporal = new DateTime();
                if (NetoInicial <= 0)
                {
                    fechaTemporal = ar.Select(p => p.Fecha).Min();
                    fechaTemporal = new DateTime(fechaTemporal.Year, fechaTemporal.Month, 1);
                }
                else
                {
                    fechaTemporal = new DateTime(FechaInicial.Year, FechaInicial.Month, 1);
                }
                while (fechaTemporal <= FechaFinal)
                {
                    listTemp.Add(fechaTemporal, 0);
                    fechaTemporal = fechaTemporal.AddMonths(1);
                }

                foreach (AporteORetiro ap in ar)
                {
                    DateTime fecha = new DateTime(ap.Fecha.Year, ap.Fecha.Month, 1);

                    if (listTemp.ContainsKey(fecha))
                    {
                        if (ap.IngresoEgreso == "I")
                        {
                            listTemp[fecha] += Convert.ToDouble(ap.Monto);
                        }
                        else
                        {
                            listTemp[fecha] -= Convert.ToDouble(ap.Monto);
                        }
                    }
                }

                if (NetoInicial > 0)
                {
                    listTemp[new DateTime(FechaInicial.Year, FechaInicial.Month, 1)] += NetoInicial;
                }
                listTemp[new DateTime(FechaFinal.Year, FechaFinal.Month, 1)] += NetoFinal;

                return new List<double>(listTemp.Values);
            }
            else
            {
                listTemp.Add(new DateTime(FechaInicial.Year, FechaInicial.Month, 1), NetoInicial);
                if (FechaInicial.Month != FechaFinal.Month)
                {
                    listTemp.Add(new DateTime(FechaFinal.Year, FechaFinal.Month, 1), NetoFinal);
                }
                else
                {
                    listTemp[new DateTime(FechaInicial.Year, FechaInicial.Month, 1)] += NetoFinal;
                }
                return new List<double>(listTemp.Values);
            }

        }
    }
}